package code15.io;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileTest {

	public static void main(String[] args) {
		//f1();
		//f2();
		
		//f3();
		
		copy("src/code15/io/a.txt");
	}
	
	/**
	 * 复制指定文件, 复制后的文件名是在原文件名后加上 "_copy" <br>
	 * 例如 : a.txt --> a_copy.txt
	 * @param path 原文件路径
	 */
	public static void copy(String path) {
		File f = new File(path);
		// 处理复制后的文件名
		StringBuffer name = new StringBuffer(f.getName());
		// 不考虑没有后缀的情况
		name.insert(name.lastIndexOf("."), "_copy");
		System.out.println("name:"+name);
		// 创建新文件的对象
		File newFile = new File(f.getParentFile(), name.toString());
		
		// 复制(读原文件内容, 写出到新文件内)
		try (
				// 构建流对象
				FileInputStream fis = new FileInputStream(f);
				FileOutputStream fos = new FileOutputStream(newFile);
				) {
			byte[] buffer = new byte[4];
			int length = 0;
			// 读到哪些
			while ( (length = fis.read(buffer)) != -1) {
				// buffer: 0, length
				// 就写出哪些
				fos.write(buffer, 0, length);
			}
			fos.flush();
			System.out.println("复制成功");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private static void f3() {
		try (
				// 根据 文件路径 构建输出流
				// 如果文件本身不存在, 则会自动创建, 如果文件存在, 会覆盖原来的内容
				// 如果文件所在的目录不存在, 则会报错
				//FileOutputStream fos = new FileOutputStream("src/code15/io/b.txt");
				// 默认是false,表示不追加, 如果为 true, 表示在原内容后追加新的内容
				FileOutputStream fos = new FileOutputStream("src/code15/io/b.txt", true);
				) {
			// 一次写一个字节
			int c = 'a';
			fos.write(c);
			String str = "hello world,测试\n";
			// 写出多个字节
			fos.write(str.getBytes("UTF-8"));
			String str2 = "-+*/123测试456789";
			// 写出一个字节数组中的部分字节
			fos.write(str2.getBytes("UTF-8"), 2, 14);
			
			// 刷新流, 确保管道中的 数据全部被输出到文件
			fos.flush();
			System.out.println("over");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}

	private static void f2() {
		// jdk7 语法 try-with-resource, 能够自动关闭外部资源
		try (
				// 在此处定义流对象, 此时操作结束后, 会自动关闭资源
				FileInputStream fis = new FileInputStream("src/code15/io/a.txt");
				// 只要是实现了 AutoCloseable 接口的 类的对象, 都可以在此定义
				) {
			byte[] buffer = new byte[4];
			int length = 0;
			while ( (length = fis.read(buffer)) != -1) {
				// 不能加换行, 如果有中文, 容易出现中文乱码
				System.out.print(new String(buffer, 0, length));
				// 不建议把字节转换为 字符
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private static void f1() {
		FileInputStream fis = null;
		try {
			// 传入 根据路径构建的 File对象
			//FileInputStream fis = new FileInputStream(new File("src/code15/io/a.txt"));
			// 传入文件的路径
			fis = new FileInputStream("src/code15/io/a.txt");
			// 一次读取一个字节, 返回int类型的表示, 会处于阻塞状态, 如果读取到文件末尾, 则返回 -1
			//int read = fis.read();
			//System.out.println((char)read);
			
			//byte[] buffer = new byte[4];
			// 一次读取部分字节到指定数组中, 返回本次读取到的字节数, 如果读取到文件末尾, 则返回 -1
			//int length = fis.read(buffer);
//			for (int i = 0; i < length; i++) {
//				System.out.print((char) buffer[i]);
//			}
			//System.out.print(new String(buffer, 0, length));
			
			// 获取当前流中可读取的字节数
			int available = fis.available();
			// 对于普通文件操作, 第一次取的值, 一般是 当前文件的大小
			System.out.println("available:"+available);
			
			byte[] buffer = new byte[4];
			int length = 0;
			while ( (length = fis.read(buffer)) != -1) {
				// 不能加换行, 如果有中文, 容易出现中文乱码
				System.out.print(new String(buffer, 0, length));
				// 不建议把字节转换为 字符
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (null != fis) {
				try {
					// 释放资源
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
}
